#include <string>
#include <iostream>
#include <sstream>
#include <cmath>
#include <cstdlib>

double random(double range) {
    double x = (rand() >> 2) / (RAND_MAX / 4.0);
    double r = x * range;

//    std::cout << "random(" << range << "): " << r << " x=" << x << "\n";

    return r;
}

void make_cluster(int ID, int size,
                  double xc, double yc, double r, bool circular) {
    for (int i=0; i<size; i++) {
        std::ostringstream label;
        label << ID << "." << i;

        double x,y;
        x = xc + random(r);
        y = yc + random(r);
        if (circular) {
            while ((x - xc)*(x - xc) + (y - yc)*(y - yc) > r*r) {
                x = xc + random(r);
                y = yc + random(r);
            }
        }
        std::cout << label.str() << " " << x << " " << y << "\n";
    }
}

int main(int argc, char *argv[]) {
    if (argc != 7) {
        std::cerr << "Usage:\n";
        std::cerr << "  make_2D_clusters #clusters #size disjoint circular xrange yrange\n";
        exit(1);
    }

    int n_clusters = atoi(argv[1]);
    int cluster_size = atoi(argv[2]);
    bool disjoint = argv[3][0] == 'y' || argv[3][0] == 'Y';
    bool circular = argv[4][0] == 'y' || argv[4][0] == 'Y';
    double x_range = atof(argv[5]);
    double y_range = atof(argv[6]);

    rand();

    std::cout << "POINT2D\n";

    if (!disjoint) {
        for (int i=0; i<n_clusters; i++) {
            double r = random(x_range/cluster_size + fmin(x_range,y_range) / 2);
            double xc = r + random(x_range - r*2);
            double yc = r + random(y_range - r*2);

            make_cluster(i, cluster_size, xc, yc, r, circular);
        }
    }

    else {
        double A = x_range / y_range;
        int H = (int)ceil(sqrt(n_clusters / A));
        int W = (int)ceil(A * H);
        int i_cluster = 0;
        double dx = x_range/W;
        double dy = y_range/H;
        double d = fmin(dx, dy);

//        std::cout << "A=" << A << " H=" << H << " W=" << W << " dx=" << dx << " dy=" << dy << " d=" << d << "\n";


        for (int i=0; i<H; i++) {
            for (int j=0; j<W; j++) {
                double r = random(d / (cluster_size*cluster_size) + d/2);
                double xc = j * dx + r + random(dx - 2*r);
                double yc = i * dy + r + random(dy - 2*r);

//                std::cout << "r=" << r << " (xc yc)=(" << xc << " " << yc << ")\n";

                make_cluster(i_cluster++, cluster_size, xc, yc, r, circular);

                if (i_cluster >= n_clusters)
                    break;

            }
        }
    }
}


